Bulk Messaging System

Documentation

Back to Home
Home Projects Bulk Messaging System Desktop Application Architecture Renderer Process Architecture UI Service Integration And IPC Communication

UI Service Integration And IPC Communication

Table of Contents#

  1. Introduction

  2. Project Structure

  3. Core Components

  4. Architecture Overview

  5. Detailed Component Analysis

  6. Dependency Analysis

  7. Performance Considerations

  8. Troubleshooting Guide

  9. Conclusion

Introduction#

This document explains how the React-based UI integrates with Electron’s main process through Inter-Process Communication (IPC), how the preload script exposes secure Node.js APIs to the renderer, and how Pyodide enables browser-based Python execution. It covers message passing patterns, error handling across process boundaries, UI update coordination, and security considerations such as context isolation.

Project Structure#

The Electron application is organized into:

  • UI layer: React components under electron/src/ui and electron/src/components

  • Electron main process: electron/src/electron/main.js orchestrates windows, IPC handlers, and services

  • Preload bridge: electron/src/electron/preload.js exposes a controlled API surface to the renderer

  • Services: Gmail and SMTP handlers under electron/src/electron

  • Pyodide utilities: electron/src/utils/pyodide.js and Python scripts under electron/dist-react/py and electron/public/py

graph TB subgraph "Renderer (React)" UI["React UI
App.jsx, main.jsx"] Components["Components
BulkMailer.jsx, WhatsAppForm.jsx"] end subgraph "Preload Bridge" Preload["preload.js
contextBridge exposeInMainWorld"] end subgraph "Main Process" Main["main.js
BrowserWindow, ipcMain handlers"] Gmail["gmail-handler.js
Gmail OAuth & send"] SMTP["smtp-handler.js
SMTP send"] PyUtil["pyodide.js
Pyodide loader"] end UI --> Components Components --> Preload Preload --> Main Main --> Gmail Main --> SMTP Components --> PyUtil PyUtil --> |loads| PyScript["parse_manual_numbers.py"]

Diagram sources

Section sources

Core Components#

  • Electron main process: Creates the BrowserWindow with context isolation enabled, registers IPC handlers for Gmail, SMTP, and WhatsApp, and manages the WhatsApp client lifecycle.

  • Preload bridge: Exposes a typed API surface to the renderer via contextBridge, wrapping ipcRenderer.invoke and ipcRenderer.on.

  • React UI: BulkMailer coordinates tabs and state, wires UI events to preload APIs, and renders real-time status updates.

  • Pyodide integration: Dynamically loads Pyodide and executes a Python script to parse manual phone numbers in the renderer.

Key responsibilities:

  • Secure exposure of Node.js capabilities through a minimal, typed API

  • Real-time status updates via event-driven IPC channels

  • Controlled rate-limiting and error propagation across processes

  • Browser-based Python execution for contact parsing

Section sources

Architecture Overview#

The UI communicates with the main process using two primary patterns:

  • Request-response via ipcRenderer.invoke and ipcMain.handle for synchronous operations

  • Event streaming via ipcRenderer.on and event.sender.send for progress/status updates

sequenceDiagram participant UI as "React Component" participant Preload as "Preload Bridge" participant Main as "Main Process" participant Service as "Service Handler" UI->>Preload : invoke("gmail-auth") Preload->>Main : ipcMain.handle("gmail-auth") Main->>Service : handleGmailAuth() Service-->>Main : {success, error?} Main-->>Preload : result Preload-->>UI : result Note over UI,Service : Progress updates use event channels UI->>Preload : onProgress(callback) Preload->>Main : ipcRenderer.on("email-progress", cb) Main->>Service : send progress via event.sender.send Service-->>Main : progress payload Main-->>Preload : emits event Preload-->>UI : callback invoked with progress

Diagram sources

Detailed Component Analysis#

IPC Handlers and UI Coordination#

  • Gmail authentication and sending:

    • Preload exposes authenticateGmail, getGmailToken, and sendEmail

    • Main registers ipcMain.handle for gmail-auth, gmail-token, and send-email

    • Gmail handler opens an OAuth window, exchanges tokens, stores credentials, and streams progress via email-progress events

  • SMTP sending:

    • Preload exposes sendSMTPEmail

    • Main registers smtp-send handler that verifies transport, sends emails, and streams progress

  • WhatsApp integration:

    • Preload exposes startWhatsAppClient, logoutWhatsApp, sendWhatsAppMessages, importWhatsAppContacts, and status listeners

    • Main creates a WhatsApp client with QR generation, emits status and QR events, and handles mass messaging with per-contact delays

sequenceDiagram participant UI as "BulkMailer.jsx" participant Preload as "preload.js" participant Main as "main.js" participant WA as "WhatsApp Client" UI->>Preload : invoke("whatsapp-start-client") Preload->>Main : ipcMain.handle("whatsapp-start-client") Main->>WA : new Client(LocalAuth) WA-->>Main : "qr", "ready", "authenticated", "disconnected" Main-->>Preload : emit("whatsapp-qr"), emit("whatsapp-status") Preload-->>UI : onWhatsAppQR/onWhatsAppStatus callbacks UI->>Preload : invoke("whatsapp-send-messages", {contacts,messageText}) Preload->>Main : ipcMain.handle("whatsapp-send-messages") Main->>WA : sendMessage for each contact Main-->>Preload : emit("whatsapp-send-status") Preload-->>UI : onWhatsAppSendStatus updates UI logs

Diagram sources

Section sources

Preload Script and Security Context#

  • The preload script uses contextBridge.exposeInMainWorld to publish a single API object electronAPI

  • It wraps:

    • Gmail: authenticateGmail, getGmailToken, sendEmail

    • SMTP: sendSMTPEmail

    • File operations: importEmailList, readEmailListFile

    • Progress: onProgress

    • WhatsApp: startWhatsAppClient, logoutWhatsApp, sendWhatsAppMessages, importWhatsAppContacts, and three status listeners

  • Security settings in BrowserWindow webPreferences:

    • nodeIntegration: false

    • contextIsolation: true

    • enableRemoteModule: false

    • webSecurity: true

    • preload path set to preload.js

classDiagram class PreloadAPI { +authenticateGmail() +getGmailToken() +sendEmail(emailData) +sendSMTPEmail(smtpData) +importEmailList() +readEmailListFile(filePath) +onProgress(callback) +startWhatsAppClient() +logoutWhatsApp() +sendWhatsAppMessages(data) +importWhatsAppContacts() +onWhatsAppStatus(callback) +onWhatsAppQR(callback) +onWhatsAppSendStatus(callback) } class ElectronAPI { <> } PreloadAPI --> ElectronAPI : "exposeInMainWorld"

Diagram sources

Section sources

Pyodide Integration for Browser-Based Python Execution#

  • The UI invokes parseManualNumbers from BulkMailer.jsx, which calls a utility in pyodide.js

  • pyodide.js dynamically loads Pyodide from a CDN, initializes it, loads the Python script from the app’s built resources, and executes a function that parses phone numbers

  • The Python script cleans and validates phone numbers, supports name-number pairs, and returns structured contact data

sequenceDiagram participant UI as "BulkMailer.jsx" participant Util as "pyodide.js" participant Py as "Pyodide Runtime" participant Script as "parse_manual_numbers.py" UI->>Util : parseManualNumbers(text) Util->>Py : loadPyodideAndScript() Py-->>Util : initialized Util->>Script : runPythonAsync(scriptText) UI->>Util : parseManualNumbers(text) Util->>Py : runPythonAsync(json.dumps(result)) Py-->>Util : resultJson Util-->>UI : JSON.parse(resultJson)

Diagram sources

Section sources

UI Update Coordination and Status Streams#

  • WhatsApp status and QR updates:

    • Main process emits “whatsapp-status”, “whatsapp-qr”, and “whatsapp-send-status”

    • Preload forwards these via ipcRenderer.on listeners

    • BulkMailer subscribes in useEffect and updates local state for display

  • Email progress:

    • Gmail and SMTP handlers send “email-progress” events during batch operations

    • Preload exposes onProgress; BulkMailer uses it to render live progress and results

flowchart TD Start(["User Action"]) --> Invoke["Invoke Preload API"] Invoke --> Handler["Main Handler Executes"] Handler --> Emit["Emit Events (status/progress)"] Emit --> Listener["Preload On Listeners"] Listener --> UIState["Update React State"] UIState --> Render["Re-render UI"] Render --> End(["User Sees Updates"])

Diagram sources

Section sources

Dependency Analysis#

  • UI depends on preload for IPC primitives and on pyodide.js for Python parsing

  • Preload depends on main process handlers for all operations

  • Main process handlers depend on external libraries (Google APIs, Nodemailer, WhatsApp Web)

  • Build system uses Vite to bundle the UI and serve from ./dist-react

graph LR UI["React UI"] --> Preload["preload.js"] Preload --> Main["main.js"] Main --> Gmail["gmail-handler.js"] Main --> SMTP["smtp-handler.js"] UI --> PyUtil["pyodide.js"] PyUtil --> PyScript["parse_manual_numbers.py"]

Diagram sources

Section sources

Performance Considerations#

  • Rate limiting: Both Gmail and SMTP handlers introduce delays between emails to avoid throttling and respect provider limits

  • Batch processing: WhatsApp sends messages with deliberate pauses to prevent rate limits and improve reliability

  • Resource cleanup: Main process deletes cached WhatsApp files on logout and app close to free disk space and avoid stale sessions

  • UI responsiveness: Event-driven updates keep the UI responsive while long-running tasks execute in the main process

[No sources needed since this section provides general guidance]

Troubleshooting Guide#

Common issues and resolutions:

  • Electron API not available in renderer:

    • Ensure preload is correctly injected via webPreferences.preload and that the app is running in Electron (not a static HTML page)

  • Gmail authentication failures:

    • Verify environment variables for client ID and secret; check OAuth redirect URI and timeouts

  • SMTP connection errors:

    • Confirm host/port/credentials; note that TLS verification is disabled for self-signed certs

  • WhatsApp QR loading failures:

    • Retry initialization; check console for QR generation errors; ensure headless mode Puppeteer arguments are valid

  • Pyodide load failures:

    • Confirm the Python script is bundled and reachable at the expected path; check network connectivity for CDN load

Section sources

Conclusion#

The application achieves secure UI-service integration by isolating the renderer, exposing a minimal IPC API via preload, and delegating sensitive operations to the main process. Real-time status and progress are delivered through event channels, while Pyodide enables robust contact parsing directly in the browser. Adhering to the documented patterns ensures reliable, maintainable, and secure inter-process communication.